package com.dankegongyu.demo.http.http.interceptor;

import androidx.annotation.NonNull;
import android.text.TextUtils;

import com.dankegongyu.demo.http.http.api.Api;
import com.dankegongyu.demo.http.util.MD5Util;

import org.json.JSONObject;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.TreeMap;

import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;

/**
 * OkHttp拦截器 公共请求参数设置
 */
@SuppressWarnings("ResultOfMethodCallIgnored")
public class ParamInterceptor implements Interceptor {

    private MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    private String OS_TYPE = "os-type";
    private String OS_VERSION = "os-ver";
    private String APP_VERSION = "app-ver";
    private String NET_TYPE = "net-type";
    private String IMEI = "imei";
    private String TIMESTAMP = "timestamp";
    private String DEVICE_UUID = "device-uuid";
    private String DEVICE_BRAND = "device-brand";
    private String DEVICE_MODEL = "device-model";
    private String CHANNEL = "app-channel";
    private String PACKAGE_NAME = "package-name";
    private String WIDTH = "width";
    private String HEIGHT = "height";
    private String IDFA = "idfa";
    private String CLIENT_ID = "ClientId"; // 个推clientId
    private String CITY_ID = "city_id"; // 当前选择的城市id
    private String LOC_LATLNG = "loc_latlng"; // 当前定位的经纬度
    private String LOC_CITY = "loc_city"; // 当前定位的城市
    private String LOC_CITY_CODE = "loc_city_code"; // 当前定位的城市编码

    @Override
    public Response intercept(@NonNull Chain chain) throws IOException {
        Request request = chain.request().newBuilder().build();
        if (request.url() != null) {
            String url = request.url().toString();
            // 如果url是非蛋壳Api的，则不需要执行下面签名等操作
            if (url != null && !url.contains(Api.BASE_URL)) {
                return chain.proceed(request);
            }
        }

        String verifyData = null;
        if (TextUtils.equals(request.method().toUpperCase(), "POST") || TextUtils.equals(request.method().toUpperCase(), "PUT")) {
            if (request.body() != null && request.body().contentLength() > 0) {
                JSONObject json = proceedPPParam(request);
                if (json != null) {
                    verifyData = proceedPPMd5(json);

                    if (TextUtils.equals(request.method().toUpperCase(), "POST")) {
                        request = proceedPostRequest(request, json);
                    } else {
                        request = proceedPutRequest(request, json);
                    }

                }
            }
        } else if (TextUtils.equals(request.method().toUpperCase(), "GET") || TextUtils.equals(request.method().toUpperCase(), "DELETE")) {
            Map<String, String> map = proceedGDParam(request);
            if (map != null) {
                verifyData = proceedGDMd5(map);

                if (TextUtils.equals(request.method().toUpperCase(), "GET")) {
                    request = proceedGetRequest(request, map);
                } else {
                    request = proceedDeleteRequest(request, map);
                }

            }
        }

        Request.Builder builder = request.newBuilder();
        JSONObject commonParam = initCommomParam();
        if (commonParam != null) {
            builder.header("X-Device-Info", commonParam.toString());
        }else {
            builder.header("X-Device-Info", "{}");
        }
        if (!TextUtils.isEmpty(verifyData)) {
            builder.header("sign", verifyData);
        }
        builder.header ("Connection", "close");
        builder.header("X-App-ID", "4");
        builder.header("X-Device-ID", "Jip70XByW6B7NybztRW715CT96XJ967hZJYfIUWd");
        builder.header("Authorization", "Bearer ae78322ab0e111e89f000050568f78f2");
        request = builder.build();
        return chain.proceed(request);
    }


    /**
     * 公共参数
     *
     * @return
     */
    private JSONObject initCommomParam() {
        try {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put(URLEncoder.encode(OS_TYPE), URLEncoder.encode("Android"));
            jsonObject.put(URLEncoder.encode(OS_VERSION), URLEncoder.encode("8.1.0"));
            jsonObject.put(URLEncoder.encode(APP_VERSION), URLEncoder.encode("V1.6.0"));
            jsonObject.put(URLEncoder.encode(NET_TYPE), URLEncoder.encode("wifi"));
            jsonObject.put(URLEncoder.encode(IMEI), URLEncoder.encode("866817038521977"));
            jsonObject.put(URLEncoder.encode(TIMESTAMP), URLEncoder.encode(String.valueOf((System.currentTimeMillis() / 1000))));
            jsonObject.put(URLEncoder.encode(DEVICE_UUID), URLEncoder.encode("Jip70XByW6B7NybztRW715CT96XJ967hZJYfIUWd"));
            jsonObject.put(URLEncoder.encode(DEVICE_BRAND), URLEncoder.encode("OnePlus"));
            jsonObject.put(URLEncoder.encode(DEVICE_MODEL), URLEncoder.encode("ONEPLUSA5010"));
            jsonObject.put(URLEncoder.encode(CHANNEL), URLEncoder.encode("umeng"));
            jsonObject.put(URLEncoder.encode(PACKAGE_NAME), URLEncoder.encode("com.dankegongyu.customer"));
            jsonObject.put(URLEncoder.encode(WIDTH), URLEncoder.encode("1080"));
            jsonObject.put(URLEncoder.encode(HEIGHT), URLEncoder.encode("2160"));
            jsonObject.put(URLEncoder.encode(IDFA), URLEncoder.encode(""));
            jsonObject.put(URLEncoder.encode(CLIENT_ID), URLEncoder.encode("45af2445d918780a2a2b0d3c59522b83"));
            jsonObject.put(URLEncoder.encode(CITY_ID), URLEncoder.encode("1"));
            jsonObject.put(URLEncoder.encode(LOC_LATLNG), URLEncoder.encode("39.928522_116.44531"));
            jsonObject.put(URLEncoder.encode(LOC_CITY), URLEncoder.encode("北京"));
            jsonObject.put(URLEncoder.encode(LOC_CITY_CODE), URLEncoder.encode("131"));
            return jsonObject;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取请求参数
     *
     * @param request 请求
     * @return
     */
    private JSONObject proceedPPParam(Request request) {
        String body = bodyToString(request.body());
        try {
            JSONObject json = new JSONObject(body);
            json.put(TIMESTAMP, String.valueOf((System.currentTimeMillis() / 1000)));
            return json;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 对请求参数进行md5
     *
     * @param json 参数
     * @return md5数据
     */
    private String proceedPPMd5(JSONObject json) {

        StringBuilder param = new StringBuilder();
        param.append("8LL3QRFpexYzlM1qI0SSEZzoBkbgqXuJKDxx1Zcx");
        param.append(json.toString());
        param.append("8LL3QRFpexYzlM1qI0SSEZzoBkbgqXuJKDxx1Zcx");

        String md5 = MD5Util.getMD5(param.toString());
        md5 = md5.toUpperCase();
        return md5;

    }

    /**
     * 重置请求
     *
     * @param request 请求
     * @param json    参数
     * @return 请求
     */
    private Request proceedPostRequest(Request request, JSONObject json) {
        RequestBody requestBody = RequestBody.create(JSON, json.toString());
        return request.newBuilder().post(requestBody).build();
    }

    /**
     * 重置请求
     *
     * @param request 请求
     * @param json    参数
     * @return 请求
     */
    private Request proceedPutRequest(Request request, JSONObject json) {
        RequestBody requestBody = RequestBody.create(JSON, json.toString());
        return request.newBuilder().put(requestBody).build();
    }

    /**
     * 获取 GET 请求参数
     *
     * @param request 请求
     * @return 参数
     */
    private Map<String, String> proceedGDParam(Request request) {
        TreeMap<String, String> map = new TreeMap<>();
        HttpUrl url = request.url();
        for (int i = 0; i < url.querySize(); i++) {
            String key = url.queryParameterName(i);
            String value = url.queryParameterValue(i);
            map.put(key, value);
        }
        map.put(TIMESTAMP, String.valueOf((System.currentTimeMillis() / 1000)));
        return map;
    }

    /**
     * 对参数进行md5
     *
     * @param map 参数
     * @return md5数据
     */
    private String proceedGDMd5(Map<String, String> map) {

        StringBuilder param = new StringBuilder();
        param.append("8LL3QRFpexYzlM1qI0SSEZzoBkbgqXuJKDxx1Zcx");
        for (String key : map.keySet()) {
            String value = map.get(key);
            param.append(key + value);
        }
        param.append("8LL3QRFpexYzlM1qI0SSEZzoBkbgqXuJKDxx1Zcx");

        String md5 = MD5Util.getMD5(param.toString());
        md5 = md5.toUpperCase();

        return md5;
    }

    /**
     * 重置请求
     *
     * @param request 请求
     * @param map     参数
     * @return 请求
     */
    private Request proceedGetRequest(Request request, Map<String, String> map) {

        String u = request.url().toString();
        int index = u.indexOf("?");
        if (index >= 0) {
            u = u.substring(0, index);
        }

        StringBuilder params = new StringBuilder();
        params.append("?");
        for (String key : map.keySet()) {
            String value = map.get(key);
            params.append(URLEncoder.encode(key) + "=" + URLEncoder.encode(value) + "&");
        }
        params = params.deleteCharAt(params.length() - 1);
        return request.newBuilder().url(u + params.toString()).build();

    }

    /**
     * 重置请求
     *
     * @param request 请求
     * @param map     参数
     * @return 请求
     */
    private Request proceedDeleteRequest(Request request, Map<String, String> map) {

        String u = request.url().toString();
        int index = u.indexOf("?");
        if (index >= 0) {
            u = u.substring(0, index);
        }
        StringBuilder params = new StringBuilder();
        params.append("?");
        for (String key : map.keySet()) {
            String value = map.get(key);
            params.append(URLEncoder.encode(key) + "=" + URLEncoder.encode(value) + "&");
        }
        params = params.deleteCharAt(params.length() - 1);
        return request.newBuilder().url(u + params.toString()).delete().build();

    }

    private String bodyToString(final RequestBody request) {
        try {
            final RequestBody copy = request;
            final Buffer buffer = new Buffer();
            if (copy != null) {
                copy.writeTo(buffer);
            } else {
                return "";
            }
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "DNW";
        }
    }

}
